/**
 * 数据迁移执行脚本
 * 使用 Node.js 直接执行迁移
 */

const { MongoClient } = require('mongodb');

// 数据库配置
const MONGODB_URI = 'mongodb+srv://1191665779:20020219aa@zn.apmsejq.mongodb.net/';
const DB_NAME = 'medical_digital_twin';

// 模拟数据
const hospitalData = {
  info: {
    name: '杭州市第一人民医院',
    level: '三级甲等',
    address: '浙江省杭州市西湖区古翠路300号',
    phone: '0571-87065701',
    totalBeds: 1200,
    dailyCapacity: 3000,
    founded: '1958年',
    staff: 2800
  },
  departments: [
    { id: 'emergency', name: '急诊科', floor: 'L1', capacity: 200, director: '陈医生', phone: '8801' },
    { id: 'internal', name: '内科', floor: 'L2', capacity: 150, director: '李医生', phone: '8802' },
    { id: 'surgery', name: '外科', floor: 'L3', capacity: 120, director: '王医生', phone: '8803' },
    { id: 'pediatrics', name: '儿科', floor: 'L2', capacity: 100, director: '张医生', phone: '8804' },
    { id: 'obstetrics', name: '妇产科', floor: 'L4', capacity: 80, director: '刘医生', phone: '8805' },
    { id: 'ophthalmology', name: '眼科', floor: 'L3', capacity: 60, director: '赵医生', phone: '8806' },
    { id: 'ent', name: '耳鼻喉科', floor: 'L3', capacity: 50, director: '孙医生', phone: '8807' },
    { id: 'dermatology', name: '皮肤科', floor: 'L2', capacity: 40, director: '周医生', phone: '8808' },
    { id: 'cardiology', name: '心血管科', floor: 'L5', capacity: 90, director: '吴医生', phone: '8809' },
    { id: 'neurology', name: '神经科', floor: 'L5', capacity: 70, director: '郑医生', phone: '8810' },
    { id: 'icu', name: 'ICU', floor: 'L6', capacity: 40, director: '朱医生', phone: '8811' },
    { id: 'or', name: '手术室', floor: 'L4', capacity: 12, director: '马医生', phone: '8812' }
  ],
  equipment: [
    { id: 'mri-01', name: 'MRI-01', type: 'MRI', location: '影像科B区', status: 'running', uptime: '95.2%', maintenance: '2024-01-08' },
    { id: 'ct-01', name: 'CT-01', type: 'CT', location: '影像科A区', status: 'running', uptime: '98.5%', maintenance: '2024-01-10' },
    { id: 'ct-02', name: 'CT-02', type: 'CT', location: '影像科A区', status: 'maintenance', uptime: '92.1%', maintenance: '2024-01-15' },
    { id: 'xray-01', name: 'X光机-01', type: 'X-Ray', location: 'L1放射科', status: 'running', uptime: '96.8%', maintenance: '2024-01-12' },
    { id: 'xray-02', name: 'X光机-02', type: 'X-Ray', location: 'L2放射科', status: 'running', uptime: '94.3%', maintenance: '2024-01-09' },
    { id: 'ultrasound-01', name: '超声波-01', type: 'Ultrasound', location: 'L3超声科', status: 'running', uptime: '97.2%', maintenance: '2024-01-11' },
    { id: 'ventilator-01', name: '呼吸机-01', type: 'Ventilator', location: 'ICU-01', status: 'running', uptime: '99.8%', maintenance: '2024-01-13' },
    { id: 'ventilator-02', name: '呼吸机-02', type: 'Ventilator', location: 'ICU-02', status: 'running', uptime: '99.5%', maintenance: '2024-01-14' },
    { id: 'or-system-01', name: '手术台-01', type: 'Surgery', location: '手术室01', status: 'running', uptime: '99.1%', maintenance: '2024-01-07' },
    { id: 'or-system-02', name: '手术台-02', type: 'Surgery', location: '手术室02', status: 'idle', uptime: '98.7%', maintenance: '2024-01-06' },
    { id: 'dialysis-01', name: '透析机-01', type: 'Dialysis', location: 'L5肾内科', status: 'running', uptime: '96.5%', maintenance: '2024-01-05' },
    { id: 'monitor-01', name: '监护仪-01', type: 'Monitor', location: 'ICU-01', status: 'running', uptime: '99.9%', maintenance: '2024-01-04' }
  ]
};

async function runMigration() {
  console.log('🚀 开始数据迁移...');

  let client;
  try {
    // 连接数据库
    console.log('📡 连接 MongoDB 数据库...');
    client = new MongoClient(MONGODB_URI);
    await client.connect();
    console.log('✅ 数据库连接成功');

    const db = client.db(DB_NAME);

    // 清空现有数据
    console.log('🧹 清空现有数据...');
    const collections = ['hospitals', 'departments', 'equipment', 'alerts', 'patient_flow', 'kpis', 'pois'];
    for (const collectionName of collections) {
      await db.collection(collectionName).deleteMany({});
    }
    console.log('✅ 现有数据已清空');

    // 1. 迁移医院数据
    console.log('🏥 迁移医院基础数据...');
    const hospitalId = `hospital_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
    const hospital = {
      id: hospitalId,
      name: hospitalData.info.name,
      level: hospitalData.info.level,
      address: hospitalData.info.address,
      phone: hospitalData.info.phone,
      totalBeds: hospitalData.info.totalBeds,
      dailyCapacity: hospitalData.info.dailyCapacity,
      founded: hospitalData.info.founded,
      staff: hospitalData.info.staff,
      center: [120.1551, 30.2741],
      bounds: {
        north: 30.2751,
        south: 30.2731,
        east: 120.1561,
        west: 120.1541
      },
      metadata: { source: 'migration', version: '1.0' },
      createdAt: new Date(),
      updatedAt: new Date()
    };
    await db.collection('hospitals').insertOne(hospital);
    console.log(`✅ 医院数据迁移完成: ${hospital.name}`);

    // 2. 迁移科室数据
    console.log('🏢 迁移科室数据...');
    const departments = hospitalData.departments.map(dept => ({
      id: `dept_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
      hospitalId: hospitalId,
      name: dept.name,
      type: mapDepartmentType(dept.id),
      floor: dept.floor,
      capacity: dept.capacity,
      director: dept.director,
      phone: dept.phone,
      position: generateDepartmentPosition(dept.floor),
      status: 'active',
      metadata: { source: 'migration', originalId: dept.id },
      createdAt: new Date(),
      updatedAt: new Date()
    }));
    await db.collection('departments').insertMany(departments);
    console.log(`✅ 科室数据迁移完成: ${departments.length} 个科室`);

    // 3. 迁移设备数据
    console.log('🔬 迁移设备数据...');
    const equipment = hospitalData.equipment.map(equip => ({
      id: `equip_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
      hospitalId: hospitalId,
      name: equip.name,
      type: mapEquipmentType(equip.type),
      location: equip.location,
      status: equip.status,
      uptime: parseFloat(equip.uptime.replace('%', '')),
      currentUtilization: Math.floor(Math.random() * 100),
      maintenance: {
        lastDate: new Date(equip.maintenance),
        nextDate: new Date(new Date(equip.maintenance).getTime() + 30 * 24 * 60 * 60 * 1000),
        status: 'scheduled'
      },
      specifications: {
        manufacturer: getManufacturer(equip.type),
        model: `${equip.type}-${equip.name}`,
        year: 2018 + Math.floor(Math.random() * 6)
      },
      metadata: { source: 'migration', originalId: equip.id },
      createdAt: new Date(),
      updatedAt: new Date()
    }));
    await db.collection('equipment').insertMany(equipment);
    console.log(`✅ 设备数据迁移完成: ${equipment.length} 台设备`);

    // 4. 迁移告警数据
    console.log('⚠️ 迁移告警数据...');
    const alerts = generateAlerts().map(alert => ({
      id: `alert_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
      hospitalId: hospitalId,
      type: alert.type,
      severity: alert.severity,
      title: alert.title,
      location: alert.location,
      description: alert.description,
      timestamp: new Date(alert.timestamp),
      status: alert.status,
      assignee: alert.assignee,
      estimatedResolution: alert.estimatedResolution,
      impact: alert.impact,
      metadata: { source: 'migration', originalId: alert.id },
      createdAt: new Date(),
      updatedAt: new Date()
    }));
    await db.collection('alerts').insertMany(alerts);
    console.log(`✅ 告警数据迁移完成: ${alerts.length} 条告警`);

    // 5. 迁移患者流量数据
    console.log('👥 迁移患者流量数据...');
    const patientFlowData = generatePatientFlowData();
    const flows = patientFlowData.map(flow => ({
      id: `flow_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
      hospitalId: hospitalId,
      hour: flow.hour,
      time: flow.time,
      patients: flow.patients,
      emergency: flow.emergency,
      outpatient: flow.outpatient,
      inpatient: flow.inpatient,
      date: new Date(),
      metadata: { source: 'migration', isWeekend: flow.hour >= 0 && flow.hour <= 6 },
      createdAt: new Date(),
      updatedAt: new Date()
    }));
    await db.collection('patient_flow').insertMany(flows);
    console.log(`✅ 患者流量数据迁移完成: ${flows.length} 条记录`);

    // 6. 迁移KPI数据
    console.log('📊 迁移KPI数据...');
    const kpis = [
      { metric: 'bedUtilization', value: 89.5, target: 85, trend: 2.1, status: 'good' },
      { metric: 'patientFlow', value: 2441, target: 2200, trend: 156, status: 'excellent' },
      { metric: 'equipmentEfficiency', value: 96.2, target: 95, trend: -0.8, status: 'excellent' },
      { metric: 'patientSatisfaction', value: 94.2, target: 90, trend: 1.8, status: 'excellent' },
      { metric: 'emergencyResponse', value: 96.5, target: 95, trend: 0.5, status: 'excellent' },
      { metric: 'averageWaitTime', value: 25, target: 25, trend: -2.3, status: 'good' }
    ].map(kpi => ({
      id: `kpi_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
      hospitalId: hospitalId,
      metric: kpi.metric,
      value: kpi.value,
      target: kpi.target,
      trend: kpi.trend,
      status: kpi.status,
      timestamp: new Date(),
      metadata: { source: 'migration' },
      createdAt: new Date(),
      updatedAt: new Date()
    }));
    await db.collection('kpis').insertMany(kpis);
    console.log(`✅ KPI数据迁移完成: ${kpis.length} 个指标`);

    // 7. 迁移POI数据
    console.log('📍 迁移POI数据...');
    const pois = hospitalData.departments.map(dept => ({
      id: `poi_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
      hospitalId: hospitalId,
      name: dept.name,
      type: mapPOIType(dept.id),
      position: generateDepartmentPosition(dept.floor),
      floor: dept.floor,
      description: `${dept.name} - ${dept.director}负责`,
      capacity: dept.capacity,
      status: 'active',
      metadata: { source: 'migration', departmentId: dept.id, director: dept.director, phone: dept.phone },
      createdAt: new Date(),
      updatedAt: new Date()
    }));
    await db.collection('pois').insertMany(pois);
    console.log(`✅ POI数据迁移完成: ${pois.length} 个点位`);

    // 创建索引
    console.log('🔍 创建数据库索引...');
    await db.collection('hospitals').createIndex({ id: 1 }, { unique: true });
    await db.collection('departments').createIndex({ hospitalId: 1 });
    await db.collection('equipment').createIndex({ hospitalId: 1 });
    await db.collection('alerts').createIndex({ hospitalId: 1 });
    await db.collection('patient_flow').createIndex({ hospitalId: 1 });
    await db.collection('kpis').createIndex({ hospitalId: 1 });
    await db.collection('pois').createIndex({ hospitalId: 1 });
    console.log('✅ 数据库索引创建完成');

    console.log('🎉 数据迁移成功完成！');
    console.log('📊 数据已成功迁移到 MongoDB 数据库');
    console.log('🔗 数据库连接: mongodb+srv://1191665779:20020219aa@zn.apmsejq.mongodb.net/');
    console.log('📁 数据库名: medical_digital_twin');
    console.log('📋 迁移统计:');
    console.log(`   - 医院: 1 个`);
    console.log(`   - 科室: ${departments.length} 个`);
    console.log(`   - 设备: ${equipment.length} 台`);
    console.log(`   - 告警: ${alerts.length} 条`);
    console.log(`   - 患者流量: ${flows.length} 条`);
    console.log(`   - KPI指标: ${kpis.length} 个`);
    console.log(`   - POI点位: ${pois.length} 个`);

  } catch (error) {
    console.error('❌ 数据迁移失败:', error);
    process.exit(1);
  } finally {
    if (client) {
      await client.close();
      console.log('🔌 数据库连接已关闭');
    }
  }
}

// 辅助函数
function mapDepartmentType(deptId) {
  const typeMap = {
    'emergency': 'emergency',
    'internal': 'outpatient',
    'surgery': 'surgery',
    'pediatrics': 'outpatient',
    'obstetrics': 'outpatient',
    'ophthalmology': 'outpatient',
    'ent': 'outpatient',
    'dermatology': 'outpatient',
    'cardiology': 'outpatient',
    'neurology': 'outpatient',
    'icu': 'inpatient',
    'or': 'surgery'
  };
  return typeMap[deptId] || 'outpatient';
}

function mapEquipmentType(type) {
  const typeMap = {
    'MRI': 'mri',
    'CT': 'ct',
    'X-Ray': 'xray',
    'Ultrasound': 'ultrasound',
    'Ventilator': 'ventilator',
    'Surgery': 'bed',
    'Dialysis': 'bed',
    'Monitor': 'bed'
  };
  return typeMap[type] || 'bed';
}

function mapPOIType(deptId) {
  const typeMap = {
    'emergency': 'emergency',
    'internal': 'department',
    'surgery': 'department',
    'pediatrics': 'department',
    'obstetrics': 'department',
    'ophthalmology': 'department',
    'ent': 'department',
    'dermatology': 'department',
    'cardiology': 'department',
    'neurology': 'department',
    'icu': 'department',
    'or': 'department'
  };
  return typeMap[deptId] || 'department';
}

function generateDepartmentPosition(floor) {
  const baseLng = 120.1551;
  const baseLat = 30.2741;
  const floorOffset = parseInt(floor.replace('L', '')) * 0.0001;
  const randomOffset = (Math.random() - 0.5) * 0.0002;
  return [baseLng + randomOffset, baseLat + floorOffset + randomOffset];
}

function getManufacturer(type) {
  const manufacturers = ['西门子', '飞利浦', 'GE', '东软', '迈瑞'];
  return manufacturers[Math.floor(Math.random() * manufacturers.length)];
}

function generateAlerts() {
  const now = new Date();
  return [
    {
      id: 'ALT-001',
      type: 'crowding',
      severity: 'high',
      title: '急诊科患者聚集告警',
      location: '急诊科等候区',
      description: '等候区患者数量超出设计容量，当前密度3.2人/㎡',
      timestamp: new Date(now.getTime() - 15 * 60 * 1000).toISOString(),
      status: 'active',
      assignee: '急诊科值班医生',
      estimatedResolution: '15分钟',
      impact: '患者等待时间增加，满意度下降'
    },
    {
      id: 'ALT-002',
      type: 'equipment',
      severity: 'medium',
      title: 'CT-02设备需要维护',
      location: '影像科A区',
      description: '设备连续运行18小时，温度传感器异常',
      timestamp: new Date(now.getTime() - 45 * 60 * 1000).toISOString(),
      status: 'in_progress',
      assignee: '医疗设备科',
      estimatedResolution: '2小时',
      impact: 'CT检查延迟，需调配其他设备'
    },
    {
      id: 'ALT-003',
      type: 'environment',
      severity: 'high',
      title: '手术室03温湿度异常',
      location: '手术室03',
      description: '温度28.5℃，湿度72%，超出手术标准',
      timestamp: new Date(now.getTime() - 8 * 60 * 1000).toISOString(),
      status: 'active',
      assignee: '手术室护士长',
      estimatedResolution: '10分钟',
      impact: '手术暂停，患者安全风险'
    }
  ];
}

function generatePatientFlowData() {
  const hourlyData = [];
  for (let h = 0; h < 24; h++) {
    let baseFlow = 0;
    if (h >= 7 && h <= 9) baseFlow = 180;
    else if (h >= 10 && h <= 11) baseFlow = 150;
    else if (h >= 14 && h <= 16) baseFlow = 160;
    else if (h >= 19 && h <= 21) baseFlow = 120;
    else if (h >= 22 || h <= 6) baseFlow = 50;
    else baseFlow = 100;

    const randomFactor = 0.85 + Math.random() * 0.3;
    const finalFlow = Math.round(baseFlow * randomFactor);

    hourlyData.push({
      hour: h,
      time: `${h.toString().padStart(2, '0')}:00`,
      patients: finalFlow,
      emergency: Math.round(finalFlow * 0.12),
      outpatient: Math.round(finalFlow * 0.78),
      inpatient: Math.round(finalFlow * 0.10)
    });
  }
  return hourlyData;
}

// 执行迁移
runMigration();
